#include "cstlparser.h"

#include <buola/algorithm/split.h>

#include <buola/gl.h>
#include <buola/scene/cmesh.h>
#include <buola/scene/cvertexdata.h>
#include <buola/scene/cindexdata.h>
#include <buola/scene/cmeshbuilder.h>

namespace buola { namespace scene { namespace import {

CSTLParser::CSTLParser()
{
}

CSTLParser::~CSTLParser()
{
}

static inline mat::CVec3d read_vec(io::PBufferStream pS)
{
    ///\todo everything here with a binaryreader
    float lVec[3];
    pS->Read(reinterpret_cast<uint8_t*>(lVec),3*sizeof(float));
    return {lVec[0],lVec[1],lVec[2]};
}

PMesh CSTLParser::Parse(const io::CURI &pURL,double pScale)
{
    std::string lBuf;

    io::PBufferStream lS=io::open_buffered(pURL,io::EMode::READ);
    lS->Ignore(80);
    
    uint32_t lNumTriangles=0;
    lS->Read(reinterpret_cast<uint8_t*>(&lNumTriangles),sizeof(lNumTriangles));

    std::vector<mat::CVec3d> lPos;
    std::vector<mat::CVec3d> lNorm;
    std::vector<int> lPosIndices,lNormIndices;
    
    for(int i=0;i<lNumTriangles;i++)
    {
        lNormIndices.push_back(lNorm.size());
        lNormIndices.push_back(lNorm.size());
        lNormIndices.push_back(lNorm.size());
        lNorm.push_back(read_vec(lS));
        lPosIndices.push_back(lPos.size());
        lPos.push_back(read_vec(lS)*pScale);
        lPosIndices.push_back(lPos.size());
        lPos.push_back(read_vec(lS)*pScale);
        lPosIndices.push_back(lPos.size());
        lPos.push_back(read_vec(lS)*pScale);
        lS->Ignore(2);
    }
    
    if(!lS) throw XData("unexpected EOF in STL parser");

    CMeshBuilder lBuilder;
    lBuilder.SetNormal(lNorm);
    lBuilder.SetPosition(lPos);
    lBuilder.SetVertices(lPosIndices,lNormIndices);
    std::vector<int> lFaces{0,(int)lPosIndices.size()};
    lBuilder.SetFaces(lFaces);
    std::vector<int> lMeshFaces{0};
    lBuilder.AddSubMesh("stl",lMeshFaces,TRIANGLES);
    return lBuilder.BuildMesh();
}

/*namespace import*/ } /*namespace scene*/ } /*namespace buola*/ }
